
from django.db import transaction
from django.db.models.query_utils import Q
from ..serializer.serializers import EnvironmentCreateSerializer, ExperimentSerializer, StuExperimentListSerializer, StuExperimentSerializer, ExperimentChapterSerializer
import traceback
from ability.excepts import LogicException
from ability.format import CustomResponse, GetPostParaOrNone
from ability.enums import ErrorCode, trans
from ..models import Environment, Experiment, Image, LogStashFile, StudentExperiment, ExperimentChapter
from rest_framework import generics, mixins, viewsets
from ability.serializer.experiment import *
from rest_framework import permissions
import ability.permissions as pm
from rest_framework import serializers
from rest_framework.response import Response
from django.http import HttpRequest
from rest_framework.serializers import Serializer
from datetime import datetime, timedelta
import json
from django.core import serializers
from rest_framework.views import APIView
from rest_framework.exceptions import ValidationError

from ..eanxing import *
import hashlib

class ExperimentListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = Experiment.objects.all()
    serializer_class = ExperimentListSerializer
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission]

    def get_queryset(self):
        queryset = Experiment.objects.all() if self.request.user.user_type == 'A' else Experiment.objects.filter(teacher=self.request.user.teacher)
        experiment_id = self.request.query_params.get('experiment_id', None)
        experiment_name = self.request.query_params.get('experiment_name', None)
        knowledge_id = self.request.query_params.get('knowledge_id', None)
        banned = [None,'']
        if experiment_id not in banned:
            queryset = queryset.filter(id=experiment_id)
        if experiment_name not in banned:
            queryset = queryset.filter(experiment_name__icontains=experiment_name)
        if knowledge_id not in banned:
            queryset = queryset.filter(knowledge__id=knowledge_id)
        queryset = queryset.filter(show="T")
        return queryset.order_by('-status','-create_time')

class ExperimentCreate(generics.CreateAPIView):

    queryset = Experiment.objects.all()
    serializer_class = ExperimentEditSerializer
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission|pm.StudentPermission]

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(ExperimentCreate, self).__init__(**kwargs)

    def post(self, request, *args, **kwargs):
        try:
            experiment_name = GetPostParaOrNone(request.data, 'experiment_name').strip()
            one = Experiment.objects.filter(experiment_name=experiment_name).first()
            duration = GetPostParaOrNone(request.data, 'duration')
            if one is not None:
                raise LogicException('实验名称已经存在,请重新取一个名称！！！')
            if experiment_name in ['',None]:
                raise LogicException('实验名称不能为空！！！')
            if len(experiment_name)>250:
                raise LogicException('实验名称的长度不能超过250个字符！！！')
            if int(duration) > 120:
                raise LogicException('实验时长最多为120分钟！！！')
            if int(duration) < 10:
                raise LogicException('实验时长最少为10分钟！！！')
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            model = serializer.save()
            model.status = 'C'
            model.save()
            user = self.request.user
            print("当前用户类型是-------->" + user.user_type)
            if (user is None or user.user_type=='S'):
                raise LogicException("请使用老师或管理员账号进行操作")
            if (user.user_type=='T'):
                model.teacher.add(self.request.user.teacher)
            else:
                model.admin.add(self.request.user.admin)
            # model.teacher.add(self.request.user.teacher)
            self.response_format['data'] = serializer.data
            return Response(self.response_format)
        except LogicException as e:
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = str(e)
        except ValidationError as e:
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            if str(e).lower().__contains__("max_length") and str(e).lower().__contains__("experiment_name"):
                self.response_format["message"] = "实验名称的长度最多为250个字符"
            elif str(e).__contains__("username already exists"):
                self.response_format["message"] = "用户名已存在"
            else:
                self.response_format["message"] = str(e)
        except Exception as e:
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = '服务器异常：'+str(e)
        return Response(self.response_format)

class ExperimentCreate2(generics.CreateAPIView):

    queryset = Experiment.objects.all()
    serializer_class = ExperimentEditSerializer
    # permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission|pm.StudentPermission]
    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(ExperimentCreate2, self).__init__(**kwargs)

    def post(self, request, *args, **kwargs):
        try:
            experiment_name = GetPostParaOrNone(request.data, 'experiment_name').strip()
            one = Experiment.objects.filter(experiment_name=experiment_name).first()
            duration = GetPostParaOrNone(request.data, 'duration')
            # 实验环境
            cidr_block = GetPostParaOrNone(request.data, 'cidr_block')
            environment_name = GetPostParaOrNone(request.data, 'environment_name')
            image = GetPostParaOrNone(request.data, 'image')
            is_open = GetPostParaOrNone(request.data, 'is_open')
            security_group = GetPostParaOrNone(request.data, 'security_group')
            subnet_name = GetPostParaOrNone(request.data, 'subnet_name')
            # 实验指导
            describe_list = GetPostParaOrNone(request.data, 'describe_list')
            create_time = GetPostParaOrNone(request.data, 'create_time')
            describe = GetPostParaOrNone(request.data, 'describe')
            detail_type = GetPostParaOrNone(request.data, 'detail_type')
            # environment_id = GetPostParaOrNone(request.data, 'environment_id')
            # experiment_name = GetPostParaOrNone(request.data, 'experiment_name')
            # id = GetPostParaOrNone(request.data, 'id')
            intro = GetPostParaOrNone(request.data, 'intro')
            price = GetPostParaOrNone(request.data, 'price')
            status = GetPostParaOrNone(request.data, 'status')
            type = GetPostParaOrNone(request.data, 'type')

            if one is not None:
                raise LogicException('实验名称已经存在,请重新取一个名称！！！')
            if experiment_name in ['',None]:
                raise LogicException('实验名称不能为空！！！')
            if len(experiment_name)>250:
                raise LogicException('实验名称的长度不能超过250个字符！！！')
            if int(duration) > 120:
                raise LogicException('实验时长最多为120分钟！！！')
            if int(duration) < 10:
                raise LogicException('实验时长最少为10分钟！！！')
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            model = serializer.save()
            user = self.request.user
            print("当前用户类型是-------->" + user.user_type)
            if (user is None or user.user_type=='S'):
                raise LogicException("请使用老师或管理员账号进行操作")
            if (user.user_type=='T'):
                model.teacher.add(self.request.user.teacher)
            else:
                model.admin.add(self.request.user.admin)
            # 创建实验环境
            # 创建一个请求对象
            experiment_new = Experiment.objects.filter(experiment_name=experiment_name).first()
            request = HttpRequest()
            request.method = 'POST'
            request.data = {
                'experiment_id': experiment_new.id,
                'cidr_block': cidr_block,
                'environment_name': environment_name,
                'image': image,
                'is_open': is_open,
                'security_group': security_group,
                'subnet_name': subnet_name}
                # 其他参数
            # 创建视图类的实例
            environment_create_view_set = EnvironmentCreateViewSet()
            # 调用 create 方法
            response = environment_create_view_set.dispatch(request)
            if response.errcode != 0:
                return response
            environment_id = response.data.id
            # 实验指导
            # request_new = HttpRequest()
            # request_new.method = 'POST'
            # 添加指导步骤
            request.data = {
                'describe_list': describe_list,
                'create_time': create_time,
                'describe': describe,
                'detail_type': detail_type,
                'environment_id': environment_id,
                'experiment_name': experiment_name,
                'id': experiment_new.id,
                'intro': intro,
                'price': price,
                'status': status,
                'type': type
            }  # 以字典形式提供需要的数据
            # 创建 ExperimentEditDesc 的实例
            experiment_edit_desc_view = ExperimentEditDesc()
            # 调用 post 方法
            response = experiment_edit_desc_view.dispatch(request)
            # 处理响应
            print(response.data)
            # model.teacher.add(self.request.user.teacher)
            self.response_format['data'] = serializer.data
            return Response(self.response_format)
        except LogicException as e:
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = str(e)
        except ValidationError as e:
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            if str(e).lower().__contains__("max_length") and str(e).lower().__contains__("experiment_name"):
                self.response_format["message"] = "实验名称的长度最多为250个字符"
            elif str(e).__contains__("username already exists"):
                self.response_format["message"] = "用户名已存在"
            else:
                self.response_format["message"] = str(e)
        except Exception as e:
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = '服务器异常：'+str(e)
        return Response(self.response_format)

class ExperimentEdit(generics.UpdateAPIView):

    queryset = Experiment.objects.all()
    serializer_class = ExperimentEditSerializer
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission|pm.StudentPermission]

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(ExperimentEdit, self).__init__(**kwargs)

    def post(self, request, *args, **kwargs):
        try:
            id = GetPostParaOrNone(request.data, 'id')
            experiment_name = GetPostParaOrNone(request.data, 'experiment_name')
            duration = GetPostParaOrNone(request.data, 'duration')
            one = Experiment.objects.filter(experiment_name=experiment_name).first()
            if (one is not None) and (id != one.id):
                raise LogicException('实验名称已经存在,请重新取一个名称！！')
            if int(duration) > 120:
                raise LogicException('实验时长最多为120分钟！！！')
            if len(experiment_name)>250:
                raise LogicException('实验名称的长度不能超过250个字符！！！')
            if int(duration) < 10:
                raise LogicException('实验时长最少为10分钟！！！')
            self.object = self.get_object()
            print("当前用户类型是-------->" + self.request.user.user_type)
            user = self.request.user
            if (user is None or user.user_type == 'S'):
                raise LogicException("请使用老师或管理员账号进行操作")
            if (user.user_type == 'T'):
                if not Experiment.belong_teacher(self.object.id, self.request.user.teacher):
                    raise LogicException('实验不存在')
            # else:
            #     if not Experiment.belong_admin(self.object.id, self.request.user.admin):
            #         raise LogicException('实验不存在')
            # if not Experiment.belong_teacher(self.object.id, self.request.user.teacher):
            #     raise LogicException('实验不存在')
            partial = kwargs.pop('partial', False)
            serializer = self.get_serializer(self.object, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            self.response_format['data'] = serializer.data
            return Response(self.response_format)
        except Experiment.DoesNotExist:
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = '实验不存在'
        except LogicException as e:
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = str(e)
        except ValidationError as e:
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            if str(e).lower().__contains__("max_length") and str(e).lower().__contains__("experiment_name"):
                self.response_format["message"] = "实验名称的长度最多为250个字符"
            elif str(e).__contains__("username already exists"):
                self.response_format["message"] = "用户名已存在"
            else:
                self.response_format["message"] = str(e)
        except Exception as e:
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = '服务器异常'
        return Response(self.response_format)

class ExperimentEditDesc(generics.UpdateAPIView):

    queryset = Experiment.objects.all()
    serializer_class = ExperimentEditDescSerializer
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission|pm.StudentPermission]

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(ExperimentEditDesc, self).__init__(**kwargs)

    def post(self, request, *args, **kwargs):
        try:
            self.object = self.get_object()
            print("当前用户类型是-------->" + self.request.user.user_type)
            user = self.request.user
            if (user is None or user.user_type == 'S'):
                raise LogicException("请使用老师或管理员账号进行操作")
            if (user.user_type == 'T'):
                if not Experiment.belong_teacher(self.object.id, self.request.user.teacher):
                    raise LogicException('实验不存在')
            # else:
            #     if not Experiment.belong_admin(self.object.id, self.request.user.admin):
            #         raise LogicException('实验不存在')
            # if not Experiment.belong_teacher(self.object.id, self.request.user.teacher):
            #     raise LogicException('实验不存在')
            partial = kwargs.pop('partial', False)
            serializer = self.get_serializer(self.object, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            serializer.save()

            experiment_id = self.object.id

            if ExperimentChapter.objects.filter(experiment_id=experiment_id).all().exists():
                experiment_data_send(experiment_id, 'update')
                self.response_format['message'] = "实验更新成功"
            else:
                experiment_data_send(experiment_id, 'add')
                self.response_format['message'] = "实验创建成功"
            # 删除老ExperimentChapter
            ExperimentChapter.objects.filter(experiment_id=experiment_id).delete()
            describes = request.data['describe_list']
            # 写入 ExperimentChapter表
            for describe in describes:
                if not describe['detail']:
                    continue
                experimentChapter = ExperimentChapter(detail=describe['detail'], experiment_id=experiment_id, create_time=datetime.now(), pv=0)
                experimentChapter.save()

            return Response(self.response_format)
        except Experiment.DoesNotExist:
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = '实验不存在'
        except LogicException as e:
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = str(e)
        except Exception as e:
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = '服务器异常'
        return Response(self.response_format)

class ExperimentEnv(generics.RetrieveAPIView):

    queryset = Experiment.objects.all()
    serializer_class = EnvironmentSerializer
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission|pm.StudentPermission]

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(ExperimentEnv, self).__init__(**kwargs)

    def get(self, request, *args, **kwargs):
        try:
            self.object = self.get_object()
            # if not Experiment.belong_teacher(self.object.id, self.request.user.teacher):
            #     raise LogicException('实验不存在')
            print("当前用户类型是-------->" + self.request.user.user_type)
            user = self.request.user
            if (user is None or user.user_type == 'S'):
                raise LogicException("请使用老师或管理员账号进行操作")
            if (user.user_type == 'T'):
                if not Experiment.belong_teacher(self.object.id, self.request.user.teacher):
                    raise LogicException('实验不存在')
            # else:
            #     if not Experiment.belong_admin(self.object.id, self.request.user.admin):
            #         raise LogicException('实验不存在')
            if self.object.environment != None:
                self.response_format['data'] = EnvironmentSerializer(self.object.environment).data
            return Response(self.response_format)
        except Experiment.DoesNotExist:
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = '实验不存在'
        except Environment.DoesNotExist:
            self.response_format['data'] = []
            return Response(self.response_format)
        except LogicException as e:
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = str(e)
        except Exception as e:
            print(str(e))
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = '服务器异常'
        return Response(self.response_format)

class EnvironmentCreateViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
    serializer_class = EnvironmentCreateSerializer 
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission]
    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(EnvironmentCreateViewSet, self).__init__(**kwargs)
    def get_object1(self, obj_id):
        try:
            return Image.objects.get(Q(id = obj_id))
        except Image.DoesNotExist:
            return None
    def perform_create(self, serializer):
        with transaction.atomic():
            tt = Experiment.objects.get(id=self.request.data['experiment_id'])
            environment_new = Environment()
            environment_new.environment_name = tt.experiment_name
            # environment_new.environment_name = self.request.data['environment_name']
            environment_new.subnet_name = self.request.data['subnet_name']
            environment_new.cidr_block = self.request.data['cidr_block']
            environment_new.is_open = str(self.request.data['is_open'])
            environment_new.security_group = str(self.request.data['security_group'])
            environment_new.save()
            # tt = Experiment.objects.get(id=self.request.data['experiment_id'])
            tt.environment = environment_new
            tt.status='N'
            tt.experiment_type=self.request.data['experiment_type'] #单实例single #双实例 double
            image_ids = GetPostParaOrNone(self.request.data, "images")
            print(image_ids)
            if image_ids:
                print("=======================")
                tt.primary_image_id = image_ids[0]
                # 如果实验环境是多镜像
                for image in image_ids:
                    obj = self.get_object1(obj_id=image)
                    environment_new.image.add(obj)
            tt.save()
        serializer = EnvironmentCreateSerializer(environment_new)
        self.response_format["data"] = serializer.data

    def create(self, request, *args, **kwargs):
        try:
            print("当前用户类型是-------->" + self.request.user.user_type)
            user = self.request.user
            if (user is None or user.user_type == 'S'):
                raise LogicException("请使用老师或管理员账号进行操作")
            if (user.user_type == 'T'):
             if Experiment.objects.filter(id=self.request.data['experiment_id'], teacher=self.request.user.teacher).count() == 0:
                self.response_format["error_code"] = ErrorCode.parameter_error.value
                self.response_format["message"] = "实验不存在"
            # else:
             # if Experiment.objects.filter(id=self.request.data['experiment_id'], admin=self.request.user.admin).count() == 0:
             #    self.response_format["error_code"] = ErrorCode.parameter_error.value
             #    self.response_format["message"] = "实验不存在"
            # if Experiment.objects.filter(id=self.request.data['experiment_id'], teacher=self.request.user.teacher).count() == 0:
            #     self.response_format["error_code"] = ErrorCode.parameter_error.value
            #     self.response_format["message"] = "实验不存在"
            super(EnvironmentCreateViewSet, self).create(request, *args, **kwargs)
            self.response_format["message"] = "实验环境创建成功"
        except Exception as e:
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = str(e)
        return Response(self.response_format)

class ExperimentOneViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    serializer_class = ExperimentSerializer
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission]

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(ExperimentOneViewSet, self).__init__(**kwargs)
    
    def get_queryset(self):
        return Experiment.objects.filter(id = self.kwargs['pk'])

    def retrieve(self, request, experiment_id=None):
        queryset = Experiment.objects.all() if self.request.user.user_type == 'A' else Experiment.objects.filter(teacher=self.request.user.teacher)
        try:
            one = queryset.get(id = self.kwargs['experiment_id'])
            serializer = ExperimentSerializer(one, context={"request": request})
            self.response_format["data"] = serializer.data
            self.response_format['data']['describe_list'] = ExperimentChapter.objects.filter(experiment_id=self.kwargs['experiment_id']).values('detail', 'pv')

        except Experiment.DoesNotExist:
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = '实验ID不存在'
        
        return Response(self.response_format)


class EnvironmentOneViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    serializer_class = EnvironmentSerializer
    serializer1_class = ExperimentSerializer
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission]

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(EnvironmentOneViewSet, self).__init__(**kwargs)
    
    def get_queryset(self):
        return Environment.objects.filter(id = self.kwargs['pk'])

    def retrieve(self, request, environment_id=None):
        queryset = Environment.objects.all() if self.request.user.user_type == 'A' else Environment.objects.filter(experiment__teacher=self.request.user.teacher)
        try:
            with transaction.atomic():
                one = queryset.get(id = self.kwargs['environment_id'])
                serializer = EnvironmentSerializer(one, context={"request": request})
                experiment =Experiment.objects.get(environment=self.kwargs['environment_id'])
                serializer1 = ExperimentSerializer(experiment,context={"request": request})
                print(type(self.response_format["data"]))
            self.response_format["data"].append(serializer.data)
            self.response_format["data"].append(serializer1.data)

        except Environment.DoesNotExist:
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = '实验环境ID不存在'
        
        return Response(self.response_format)

class ExperimentSetStatus(APIView):

    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission]

    def get_object(self, obj_id):
        try:
            ret = Experiment.objects.get(id = obj_id) if self.request.user.user_type == 'A' else Experiment.objects.get(id = obj_id, teacher=self.request.user.teacher)
            return ret
        except Experiment.DoesNotExist:
            return None

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(ExperimentSetStatus, self).__init__(**kwargs)

    def post(self, request, *args, **kwargs):
        try:
            id = GetPostParaOrNone(request.data, 'id')
            status = GetPostParaOrNone(request.data, 'status')
            if status not in ['N', 'C']:
                raise LogicException('参数有误')
            self.object = self.get_object(id)
            if self.object is None:
                raise LogicException('数据不存在')
            self.object.status = status
            if(status == 'N'):
              if (len(Experiment.objects.filter(id = id))==0 or Experiment.objects.filter(id = id).first().environment is None):
                raise LogicException('当前实验没有实验环境，不可以上架！！！')
            self.object.save()
            self.response_format['message'] = '操作成功'

            # if status == 'N':
            #     action = 'update'
            # else:
            #     action = 'delete'
            action = 'update'
            experiment_data_send(id, action)
            return Response(self.response_format)
        except LogicException as e:
            self.response_format['error_code'] = ErrorCode.parameter_error.value
            self.response_format['message'] = str(e)
        except Exception as e:
            traceback.print_exc()
            self.response_format['error_code'] = ErrorCode.parameter_error.value
            self.response_format['message'] = '服务器异常'
        return Response(self.response_format)

class ExperimentSetShow(APIView):

    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission]

    def get_object(self, obj_id):
        try:
            ret = Experiment.objects.get(id = obj_id) if self.request.user.user_type == 'A' else Experiment.objects.get(id = obj_id, teacher=self.request.user.teacher)
            return ret
        except Experiment.DoesNotExist:
            return None

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(ExperimentSetShow, self).__init__(**kwargs)

    def post(self, request, *args, **kwargs):
        try:
            experiment = GetPostParaOrNone(request.data, 'o')
            show = GetPostParaOrNone(request.data, 'show')
            if show not in ['F']:
                raise LogicException('参数有误')
            self.object = self.get_object(experiment['id'])
            if self.object is None:
                raise LogicException('数据不存在')
            if (experiment['live_ins_count']>0):
                raise LogicException('当前实验存在存活实例，不可以被删除/ToT/')
            if (experiment['status']=='N'):
                raise LogicException('不可以删除上架的实验/ToT/')
            self.object.show = show
            self.object.save()
            self.response_format['message'] = '删除成功'
            action = 'delete'
            experiment_data_send(experiment['id'], action)
            return Response(self.response_format)
        except LogicException as e:
            self.response_format['error_code'] = ErrorCode.parameter_error.value
            self.response_format['message'] = str(e)
        except Exception as e:
            traceback.print_exc()
            self.response_format['error_code'] = ErrorCode.parameter_error.value
            self.response_format['message'] = '服务器异常'
        return Response(self.response_format)


class ReSetPassWord(APIView):
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission]
    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(ReSetPassWord, self).__init__(**kwargs)

    def post(self, request, *args, **kwargs):
        try:
            user_id = request.user.id
            if not user_id:
                raise LogicException('用户不存在')
            oldPwd = GetPostParaOrNone(request.data, 'oldPwd')
            newPwd = GetPostParaOrNone(request.data, 'newPwd')
            rePwd = GetPostParaOrNone(request.data, 'rePwd')
            user = UserProfile.objects.filter(id=user_id).first()
            if user is None:
                raise LogicException('用户不存在')
            if hashlib.md5(oldPwd.encode()).hexdigest() != user.pwd:
                raise LogicException('输入正确的原密码')
            user.pwd = hashlib.md5(newPwd.encode()).hexdigest()
            user.save()
            self.response_format['message'] = '修改密码成功，请重新登录！！'
            return Response(self.response_format)
        except LogicException as e:
            self.response_format['error_code'] = ErrorCode.parameter_error.value
            self.response_format['message'] = str(e)
        except Exception as e:
            traceback.print_exc()
            self.response_format['error_code'] = ErrorCode.parameter_error.value
            self.response_format['message'] = '服务器异常'
        return Response(self.response_format)


class InstanceListAPIView(generics.ListAPIView):
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission]
    serializer_class = InstanceListSerializer
    model = serializer_class.Meta.model
    queryset = Instance.objects.all()
    def get_queryset(self):
        environment_id = self.kwargs['environment_id']
        queryset = self.model.objects.filter(environment__id=environment_id).order_by('id') if self.request.user.user_type == 'A' else self.model.objects.filter(environment__id=environment_id,environment__experiment__teacher=self.request.user.teacher).order_by('id')
        queryset = queryset.filter(status='N')
        return queryset

class InstanceRecoveryView(APIView):

    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission]
    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        self.message = ""
        super(InstanceRecoveryView, self).__init__(**kwargs)
    
    def get_object(self, obj_id):
        try:
            ret = Instance.objects.get(id = obj_id) if self.request.user.user_type == 'A' else Instance.objects.get(id = obj_id, environment__experiment__teacher=self.request.user.teacher)
            return ret
        except Instance.DoesNotExist:
            return None

    def validate_ids(self, id_list):
        for id in id_list:
            Instance.objects.get(id = id)
        return True

    def post(self, request, *args, **kwargs):
        try:
            id_list = request.data['instances']
            instances = []
            for id in id_list:
                obj = self.get_object(obj_id=id)
                if obj == None:
                    self.response_format["error_code"] = ErrorCode.parameter_error.value
                    self.message += '实例ID:'+str(id)+'不存在\n'
                    continue
                ci = CloudInstance()
                try:
                    if ci.recovery([obj.instanceId]):
                        obj.status = "C"
                        obj.save()
                        self.message += '实例ID:'+str(id)+'回收成功\n'
                        instances.append(obj)
                    else:
                        self.response_format["error_code"] = ErrorCode.parameter_error.value
                        self.message += '实例ID:'+str(id)+'回收失败\n'
                        continue
                except TencentCloudSDKException as e:
                    if e.code == 'InvalidInstanceId.NotFound':
                        obj.status = "C"
                        obj.save()
                        self.message += '实例ID:' + str(id) + '回收成功\n'
                        instances.append(obj)
                        continue;
                    else:
                        if str(e).__contains__("Request-sent"):
                            self.response_format["message"] = "正在回收中"
                        else:
                            self.response_format["message"] = str(e.get_message())
                        return Response(self.response_format)
            self.response_format["message"] = self.message
            return Response(self.response_format)
        except Exception as e:
            traceback.print_exc()
            self.response_format["message"] = str(e)
            return Response(self.response_format)

class ReportListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):

    """
    API endpoint that allows users to be viewed or edited.
    """
    get_queryset = queryset = Report.objects.all()
    serializer_class = TeacherReportListSerializer 
    permission_classes = [pm.CustomIsAuthenticated, pm.AdminPermission|pm.TeacherPermission]

    def get_queryset(self):
        # queryset = Report.objects.filter(experiment__teacher = self.request.user.teacher)
        experiment_id = self.request.query_params.get('experiment_id', None)
        experiment_name = self.request.query_params.get('experiment_name', None)
        report_title = self.request.query_params.get('report_title', None)
        report_status = self.request.query_params.get('report_status', None)
        studentid = self.request.query_params.get('studentid', None)
        username = self.request.query_params.get('username', None)
        banned = [None,'']
        if experiment_id not in banned:
            queryset = Report.objects.filter(experiment_id=experiment_id)
        if experiment_name not in banned:
            queryset = queryset.filter(experiment__experiment_name__icontains=experiment_name)
        if report_title not in banned:
            queryset = queryset.filter(title__icontains=report_title)
        if report_status not in banned:
            queryset = queryset.filter(score__isnull=True) if str(report_status) == "0" else queryset.filter(score__isnull=False)
        if studentid not in banned:
            queryset = queryset.filter(student__studentID=studentid)
        if username not in banned:
            queryset = queryset.filter(student__user__real_name__icontains=username)
        
        return queryset.order_by('-id')

class PcVNCView(APIView):

  queryset = Experiment.objects.all()
  serializer_class = StuExperimentListSerializer
  permission_classes = [pm.AllowAny]

  def __init__(self, **kwargs):
    print('PcVNCView init')
    self.response_format = CustomResponse().response
    super(PcVNCView, self).__init__(**kwargs)

  def initial(self, request, *args, **kwargs):
    """
    Runs anything that needs to occur prior to calling the method handler.
    """
    self.format_kwarg = self.get_format_suffix(**kwargs)

    # Perform content negotiation and store the accepted info on the request
    neg = self.perform_content_negotiation(request)
    request.accepted_renderer, request.accepted_media_type = neg

    # Determine the API version, if versioning is in use.
    version, scheme = self.determine_version(request, *args, **kwargs)
    request.version, request.versioning_scheme = version, scheme

    # Ensure that the incoming request is permitted
    try:
        print('before perform_authentication')
        print(request.user)
        self.perform_authentication(request)
        print('before check_permissions')
        self.check_permissions(request)
        print('before check_throttles')
        self.check_throttles(request)
        print('after check_throttles')
    except Exception as e:
    #   traceback.print_exc()
      print(str(e))

  def post(self, request, *args, **kwargs):
    
    try:
      print(request.META, request.data)
      experiment = StudentExperiment.objects.get(experiment_id=request.data['id'], vnccode=request.data['vnccode'])
      if experiment is None:
        raise LogicException('错误的请求')

      if experiment.experiment.status != 'N':
        raise LogicException('该实验已经结束')
    
      if request.data['vnccode'] == '3eeaex0g' and request.data['id'] == 50:
        self.response_format['data'] = {
            'isDemo': 1,
            'detail_type': experiment.experiment.detail_type,
            'describe': experiment.experiment.describe,
            'experiment_name': experiment.experiment.experiment_name
        }
        return Response(self.response_format)

      serializer = StuExperimentSerializer(experiment.experiment, context={"student": experiment.student})

      self.response_format['data'] = serializer.data
      self.response_format['data']['isDemo'] = 0
      return Response(self.response_format)
    except StudentExperiment.DoesNotExist:
      self.response_format["error_code"] = ErrorCode.parameter_error.value
      self.response_format["message"] = "数据不存在"
      return Response(self.response_format)
    except LogicException as e:
      traceback.print_exc()
      print(str(e))
      self.response_format["error_code"] = ErrorCode.parameter_error.value
      self.response_format["message"] = str(e)
      return Response(self.response_format)
    except Exception as e:
      traceback.print_exc()
      print(str(e))
      self.response_format["error_code"] = ErrorCode.parameter_error.value
      self.response_format["message"] = str(e)
      return Response(self.response_format)

class InsEventView(APIView):
    serializer_class = InsEventCreateSerializer 
    permission_classes = [permissions.AllowAny]

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(InsEventView, self).__init__(**kwargs)

    def initial(self, request, *args, **kwargs):
        try:
            super().initial(request, *args, **kwargs)
        except Exception as e:
        #    traceback.print_exc()
           print(str(e)) 

    def post(self, request, *args, **kwargs):
        try:
            print(request.data)
            self.experiment = StudentExperiment.objects.get(experiment_id=request.data['id'], vnccode=request.data['vnccode'])
            if self.experiment is None:
                raise LogicException('错误的请求')
            cols = ['etype', 'down', 'xpos', 'ypos', 'event', 'key', 'input_str']
            with transaction.atomic():
                _new = InsEvent()
                for i in cols:
                    attr = GetPostParaOrNone(request.data, i)
                    if attr is not None:
                        setattr(_new, i, attr)
                print(_new)
                _new.user = self.experiment.student.user
                _new.experiment = self.experiment.experiment
                insId = GetPostParaOrNone(self.request.data, 'insId')
                ins = Instance.objects.get(instanceId=insId)
                _new.image = ins.image
                _new.save()
        except Exception as e:
            print(str(e))
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = str(e)
        return Response(self.response_format)

class LogstashView(APIView):
    serializer_class = InsEventCreateSerializer 
    permission_classes = [permissions.AllowAny]

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(LogstashView, self).__init__(**kwargs)
    
    def initial(self, request, *args, **kwargs):
        try:
            super().initial(request, *args, **kwargs)
        except Exception as e:
        #    traceback.print_exc()
           print(str(e)) 

    def post(self, request, *args, **kwargs):
        try:
            remote_addr = request.META['REMOTE_ADDR']
            print(request.data, remote_addr)
            message = GetPostParaOrNone(request.data, 'message')
            host = GetPostParaOrNone(request.data, 'host')
            path = GetPostParaOrNone(request.data, 'path')
            version = GetPostParaOrNone(request.data, '@version')
            timestamp = GetPostParaOrNone(request.data, '@timestamp')
            LogStashFile.add(remote_addr, message, host, path, version, timestamp)
        except Exception as e:
            print(str(e))
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = str(e)
        return Response(self.response_format)

class LogstashListView(APIView):
    serializer_class = InsEventCreateSerializer 
    permission_classes = [permissions.AllowAny]

    def __init__(self, **kwargs):
        self.response_format = CustomResponse().response
        super(LogstashListView, self).__init__(**kwargs)
    
    def initial(self, request, *args, **kwargs):
        try:
            super().initial(request, *args, **kwargs)
        except Exception as e:
           traceback.print_exc()
           print(str(e)) 

    def post(self, request, *args, **kwargs):
        try:
            id = request.data['id']
            vnccode = request.data['vnccode']
            lastid = request.data['lastid']
            remote_addr = request.data['remote_addr']

            experiment = StudentExperiment.objects.get(experiment_id=id, vnccode=vnccode)

            if experiment is None:
                raise LogicException('错误的请求')

            if experiment.experiment.status != 'N':
                raise LogicException('该实验已经结束')
            # 取一个小时内的
            last_hour_date_time = datetime.now() - timedelta(hours = 1)
            log = LogStashFile.objects.filter(remote_addr=remote_addr, id__gt=lastid, timestamp__gt=last_hour_date_time).all()
            data = []
            for l in log:
                data.append({
                    "id": l.id,
                    "message": l.message,
                    "host": l.host,
                    "path": l.path,
                    "timestamp": l.timestamp.strftime("%Y-%m-%d %H:%M:%S")
                })
            self.response_format['data'] = data
        except Exception as e:
            print(str(e))
            traceback.print_exc()
            self.response_format["error_code"] = ErrorCode.parameter_error.value
            self.response_format["message"] = str(e)
        print(self.response_format)
        return Response(self.response_format)
